#include"redis_connect.h"
#include<stdexcept>
#include<string.h>
#include<iostream>
using namespace std;
redis_manager::redis_manager(const string &host ,int port)//的地址，端口号
{
    context=redisConnect(host.c_str(),port);
    if(context==NULL||context->err)
    {
        throw runtime_error("redis connext failed");
    }
}

redis_manager::~redis_manager()
{
    redisFree(context);
}

//在设置对应账户的信息列表
bool redis_manager::lpush_message(const string &key,const string &value,string &send_account)
{
    string messages=send_account+value;

    redisReply *reply=(redisReply *)redisCommand(context,"lpush %s %s",(key+"list").c_str(),messages.c_str());
    bool result = false;

    if(reply==NULL )
    {
        cerr<<"Redis command execution failed"<<endl;
        return false;
    }
    if(reply->type==REDIS_REPLY_INTEGER && reply->integer>0)
    result = true;

    freeReplyObject(reply);
    return result;
}

//获取对应客户信息列表的信息
string redis_manager::rpop_message(const string &key)
{
    redisReply* reply=(redisReply*)redisCommand(this->context,"rpop %s",(key+"list").c_str());
    string result ="";
    if(reply==NULL)
    {
        cerr <<key<<":" <<"Redis command execution failed" << endl;
        return result;//null值不需要free
    }
    if(reply->type==REDIS_REPLY_STRING )
    {
        result=string(reply->str);
    }
    else if(reply->type==REDIS_REPLY_NIL)
    {
        cout<<key<<"list无信息"<<endl;
    }
    else if(reply->type==REDIS_REPLY_ERROR)
    {
        cout<<key<<"Redis error:"<<endl;
    }
    freeReplyObject(reply);
    return result;
}
bool redis_manager::check_key(string key)
{
    cout<<"检测"<<endl;
    redisReply* reply=(redisReply*)redisCommand(this->context,"exists %s",key.c_str());
    if(reply==NULL)
    {
        cout<<"Redis 命令执行失败"<<endl;
        return false;
    }
    if(reply->type=REDIS_REPLY_INTEGER && reply->integer==1)
    {
        freeReplyObject(reply);
        cout<<"存在"<<endl;
        return true;
    }
    else if(reply->type==REDIS_REPLY_INTEGER && reply->integer==0)
    {
        cout<<"不存在"<<endl;
        freeReplyObject(reply);
        return 0;
    }
    return false;
}
//尝试获取锁
bool redis_manager::try_reislock(string account)
{
    string client_id="lock";
    // 使用SET命令加锁（NX: 仅当键不存在时设置，EX: 过期时间10秒）
    redisReply* reply = (redisReply*)redisCommand(
        this->context, "SET %s %s NX EX 20", 
        account.c_str(), client_id.c_str()
    );
    
    // 3. 错误处理（先检查reply是否为NULL，避免野指针）
    if (!reply) {
        cout << "Redis命令执行失败,错误信息: " <<  endl;
        // 注意：NULL指针不能调用freeReplyObject，否则崩溃
        return false;
    }

    // 4. 校验返回值类型和内容（使用字符串比较而非指针）
    bool lock_acquired = false;
    if (reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {
        cout << "账号 " << account << " 上锁成功"<< endl;
        lock_acquired = true;
    } else {
        cout << "上锁失败，返回类型: " << reply->type 
             << ", 内容: " << (reply->str ? reply->str : "NULL") << endl;
    }
    
    // 5. 释放资源（无论是否成功都释放）
    freeReplyObject(reply);
    return lock_acquired;
}


//释放锁
bool redis_manager::unlock(string account)
{
    cout<<account<<endl;
    redisReply* reply=(redisReply*)redisCommand(this->context,"del %s",account.c_str());
    if (!reply) {
            std::cerr << "Redis 命令执行失败" << std::endl;
            return false;
    }
   
    if (!reply) {
        cout << "解锁命令执行失败，错误信息: " <<  endl;
        return false;
    }
    
    // 2. 处理返回结果
    bool unlock_success = false;
    if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) {
        cout << "账号 " << account << " 解锁成功" << endl;
        unlock_success = true;
    } else {
        cout << "解锁失败，可能锁已过期或非当前客户端持有" << endl;
    }
    
    freeReplyObject(reply);
    return unlock_success;
}

int redis_manager::check_key_exsits(string &account)
{
    string key=account+"list";
    redisReply* reply=(redisReply*)redisCommand(this->context,"exists %s",key.c_str());
    if(reply==NULL)
    {
        cout<<"Redis 命令执行失败"<<endl;
        return -1;
    }
    if(reply->type=REDIS_REPLY_INTEGER && reply->integer==1)
    {
        freeReplyObject(reply);
        return 1;
    }
    else if(reply->type==REDIS_REPLY_INTEGER && reply->integer==0)
    {
        freeReplyObject(reply);
        return 0;
    }
    return -1;
}

string redis_manager::get_message(string account)
{
    string key =account+"list";
    redisReply* reply=(redisReply*)redisCommand(this->context,"lindex %s -1",key.c_str());
    string result ="";
    if(reply==NULL)
    {
        cerr <<account<<":" <<"Redis command execution failed" << endl;
        return result;//null值不需要free
    }
    if(reply->type==REDIS_REPLY_STRING )
    {
        result=string(reply->str,reply->len);
    }
    else if(reply->type==REDIS_REPLY_NIL)
    {
        cout<<account<<"list无信息"<<endl;
    }
    else if(reply->type==REDIS_REPLY_ERROR)
    {
        cout<<account<<"Redis error:"<<endl;
    }
    freeReplyObject(reply);
    return result;
}